package org.xxpay.pay.channel.ysepay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.AmountUtil;
import org.xxpay.core.common.util.DateUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayDivisionRecord;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BaseDivision;
import org.xxpay.pay.channel.PayConfig;
import org.xxpay.pay.channel.ysepay.util.Https;
import org.xxpay.pay.channel.ysepay.util.SignUtils;
import org.xxpay.pay.service.CommonService;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author terrfly
 * @Date 2019/2/21 21:58
 * @Description 分账接口
 **/

@Service
public class YsepayDivisionService extends BaseDivision {

    private static final MyLog logger = MyLog.getLog(YsepayDivisionService.class);

    @Autowired
    private CommonService commonService;

    @Autowired
    public PayConfig payConfig;


    public String getChannelName() {
        return YsepayConfig.CHANNEL_NAME_YSEPAY;
    }



    public PayDivisionRecord division(PayOrder payOrder){

        PayDivisionRecord returnObj = new PayDivisionRecord();
        String logPrefix = "【银盛订单分账申请】";

        try {
            if(PayConstant.PAY_STATUS_SUCCESS != payOrder.getStatus() && PayConstant.PAY_STATUS_COMPLETE != payOrder.getStatus()){
                logger.info("{}订单未完成，无需做分账处理。", logPrefix);
                return null;
            }

            YsepayConfig ysepayConfig = new YsepayConfig(getPayParam(payOrder));
            Date nowTime = new Date();
            Map<String, String> reqParamMap = new HashMap<>();
            reqParamMap.put("method", "ysepay.single.division.online.accept");	//分账登记
            reqParamMap.put("partner_id", ysepayConfig.getDivisionSellerId()); //商户在银盛支付平台开设的用户号[商户号]
            reqParamMap.put("timestamp", DateUtil.date2Str(nowTime)); //发送请求的时间，格式"yyyy-MM-dd HH:mm:ss"
            reqParamMap.put("charset", YsepayConfig.CHARSET); //商户网站使用的编码格式
            reqParamMap.put("sign_type", "RSA"); //RSA
            reqParamMap.put("notify_url", super.getNotifyDivisionUrl(getChannelName(), null)); //异步通知地址
            reqParamMap.put("version", "3.0"); //接口版本

            //业务参数
            JSONObject bizContentJSON = new JSONObject();
            bizContentJSON.put("out_trade_no", payOrder.getPayOrderId());  //原订单号
            bizContentJSON.put("payee_usercode", ysepayConfig.getSellerId());   //主商户号（原交易收款方）
            bizContentJSON.put("total_amount", AmountUtil.convertCent2Dollar(payOrder.getAmount() + ""));   //原订单交易金额，20长度位，保留2位小数

            bizContentJSON.put("is_divistion", "01");   //原订单是否参与分账01：是，02否
            bizContentJSON.put("is_again_division","N");    //是否重新分账Y：是，N：否
            bizContentJSON.put("division_mode","02");   //分账模式01 ：比例，02：金额

            JSONArray divArray = new JSONArray();
            List<PayDivisionRecord> divs = commonService.payDivisionRecordService.selectByPayOrderId(payOrder.getPayOrderId());
            for(PayDivisionRecord div : divs){
                JSONObject bizDiv = new JSONObject();
                bizDiv.put("division_mer_usercode", div.getChannelMchId());    //分账商户号

                if(3 == div.getInfoType()){  //平台商户
                    //分账金额 = 平台收益  + 平台手续费
                    bizDiv.put("div_amount",  AmountUtil.convertCent2Dollar(div.getDivisionAmount() + payOrder.getChannelCost() +  "" ));   //分账金额
                    //将通道手续费在平台商户中扣除。
                    bizDiv.put("is_chargeFee", "01");   //是否收取手续费（01：是，02否）
                }else{

                    if(div.getDivisionAmount() <= 0) continue; //金额为0的商户 不进行分账
                    bizDiv.put("div_amount",  AmountUtil.convertCent2Dollar(div.getDivisionAmount() + "" ));   //分账金额
                    bizDiv.put("is_chargeFee", "02");   //是否收取手续费（01：是，02否）
                }

                divArray.add(bizDiv);
            }

            bizContentJSON.put("div_list", divArray);   //分账明细
            reqParamMap.put("biz_content", bizContentJSON.toJSONString());

            //获取 分账配置私钥
            String privatePfxFilePath = payConfig.getCertRootPath() + File.separator + getChannelName() + File.separator + ysepayConfig.getDivisionPrivatePfxPath();

            //签名
            String signStr = SignUtils.rsaSign(reqParamMap, privatePfxFilePath, ysepayConfig.getDivisionPfxPwd());
            reqParamMap.put("sign", signStr); //RSA签名字符串，再用Base64编码

            //请求接口
            logger.info("ysepay req reqParamMap: {}", reqParamMap);
            String resStr = Https.httpsSend(YsepayConfig.DIVISION_REQ_URL, reqParamMap);
            logger.info("ysepay resData: {}", resStr);

            if(StringUtils.isEmpty(resStr)){
                throw new Exception("返回数据为null");
            }
            JSONObject resJSON = JSON.parseObject(resStr, Feature.OrderedField); //保持原始对象顺序

            String resSign = resJSON.getString("sign");  //返回数据的签名
            JSONObject resBizJSON = resJSON.getJSONObject("ysepay_single_division_online_accept_response");

            //分账 银盛公钥文件
            String publicCerFilePath = payConfig.getCertRootPath() + File.separator + getChannelName() + File.separator + ysepayConfig.getDivisionPublicCerPath();

            boolean isTrue = SignUtils.rsaCheckContent(publicCerFilePath, resBizJSON.toJSONString(), resSign);
            if(!isTrue){
                throw new Exception("验签失败！");
            }

            //分账中
            if("0000".equals(resBizJSON.get("code")) || "01".equals(resBizJSON.get("code")) || "02".equals(resBizJSON.get("code")) ){
                returnObj.setStatus(MchConstant.DIVISION_STATUS_ING);
            }

            else if("00".equals(resBizJSON.get("code")) ){
                returnObj.setStatus(MchConstant.DIVISION_STATUS_SUCCESS);
            }
            else if("99".equals(resBizJSON.get("code")) ){
                returnObj.setStatus(MchConstant.DIVISION_STATUS_ERROR);
                returnObj.setChannelErrorMsg(resBizJSON.toString());
            }else{
                logger.error("分账返回状态未知， resBizJSON={} ", resBizJSON.toJSONString());
                return null;
            }
            return returnObj;

        } catch (Exception e) {
            logger.error("{}ysepay error", e, logPrefix);
            returnObj.setStatus(MchConstant.DIVISION_STATUS_ERROR);
            returnObj.setChannelErrorMsg(e.getMessage());
        }

        return returnObj;
    }


    public static void main(String[] args) throws Exception {

        Date nowTime = new Date();
        Map<String, String> reqParamMap = new HashMap<>();
        reqParamMap.put("method", "ysepay.single.division.online.query");	//分账查询
        reqParamMap.put("partner_id", "mzrhwlkj");
        reqParamMap.put("timestamp", DateUtil.date2Str(nowTime)); //发送请求的时间，格式"yyyy-MM-dd HH:mm:ss"
        reqParamMap.put("charset", YsepayConfig.CHARSET); //商户网站使用的编码格式
        reqParamMap.put("sign_type", "RSA"); //RSA
        reqParamMap.put("version", "3.0"); //接口版本

        JSONObject biz = new JSONObject();
        biz.put("src_usercode", "mzrhwlkj");
        biz.put("out_trade_no", "P01201902221544178120001");
        reqParamMap.put("biz_content", biz.toJSONString());

        //获取 分账配置私钥
        String privatePfxFilePath = "E:\\junyi\\testKey\\ysepay\\kj\\mz.pfx";

        //签名
        String signStr = SignUtils.rsaSign(reqParamMap, privatePfxFilePath, "123654aA");
        reqParamMap.put("sign", signStr); //RSA签名字符串，再用Base64编码


        String resStr = Https.httpsSend(YsepayConfig.DIVISION_REQ_URL, reqParamMap);

        System.out.println(resStr);

    }






}
